import React, {
  useState,
  useEffect,
} from 'react'
import classNames from 'classnames'
import { withNativeProps } from '../../utils/native-props'
import type { WaterMarkProps } from './type'

const classPrefix = 'rt-water-mark'

export const WaterMark: React.FC<WaterMarkProps> = (props) => {
  const {
    content,
    fontStyle = 'normal',
    fontWeight = 'normal',
    fontColor = 'rgba(0,0,0,.15)',
    fontSize = 14,
    fontFamily = 'sans-serif',
    fullPage = true,
    gapX = 24,
    gapY = 48,
    height = 64,
    image,
    imageWidth = 120,
    imageHeight = 64,
    rotate = -22,
    width = 120,
    zIndex,
  } = props

  const [base64Url, setBase64Url] = useState('')

  useEffect(() => {
    const canvas = document.createElement('canvas')
    const ratio = window.devicePixelRatio
    const ctx = canvas.getContext('2d')
    const cw = `${(gapX + width) * ratio}px`
    const ch = `${(gapY + height) * ratio}px`
    canvas.setAttribute('width', cw)
    canvas.setAttribute('height', ch)

    if (ctx) {
      if (image) {
        ctx.save()
        ctx.translate(((gapX + width) * ratio) / 2, ((gapY + height) * ratio) / 2)
        ctx.rotate((Math.PI / 180) * Number(rotate))

        const img = new Image()
        img.crossOrigin = 'anonymous'
        img.referrerPolicy = 'no-referrer'
        img.onload = () => {
          ctx.drawImage(
            img,
            (-imageWidth * ratio) / 2,
            (-imageHeight * ratio) / 2,
            imageWidth * ratio,
            imageHeight * ratio,
          )
          ctx.restore()
          setBase64Url(canvas.toDataURL())
        }
        img.src = image
      } else if (content) {
        ctx.save()
        // default: bottom
        ctx.textBaseline = 'middle'
        // default: start
        ctx.textAlign = 'center'
        // 原点→画布中心
        ctx.translate(((gapX + width) * ratio) / 2, ((gapY + height) * ratio) / 2)
        // 文字绕中间旋转（参数为弧度）
        ctx.rotate((Math.PI / 180) * Number(rotate))

        const markSize = Number(fontSize) * ratio
        const lineHeight = markSize * 1.2
        ctx.font = `${fontStyle} normal ${fontWeight} ${markSize}px/${lineHeight}px ${fontFamily}`
        ctx.fillStyle = fontColor
        const lines = Array.isArray(content) ? content : [content]
        /**
         * top = - (整体高度 - lineHeight) / 2
         * = - (整体高度 / 2 - lineHeight / 2)
         * = - (lines.length * lineHeight / 2 - lineHeight / 2)
         * = - (lines.length - 1) * lineHeight / 2
         */
        const top = (-(lines.length - 1) * lineHeight) / 2
        lines.forEach((txt, i) => ctx.fillText(txt, 0, top + i * lineHeight))
        ctx.restore()
        setBase64Url(canvas.toDataURL())
      }
    } else {
      throw new Error('RT Canvas is not supported in the current environment')
    }
  }, [
    gapX,
    gapY,
    rotate,
    fontStyle,
    fontWeight,
    width,
    height,
    fontFamily,
    fontColor,
    image,
    imageHeight,
    imageWidth,
    content,
    fontSize,
  ])

  return withNativeProps(
    props,
    <div
      className={classNames(classPrefix, {
        [`${classPrefix}-full-page`]: fullPage,
      })}
      style={{
        zIndex: zIndex ?? 'unset',
        backgroundSize: `${(gapX + width)}px`,
        // Not give `url` if its empty. Which will cause 404 error.
        backgroundImage: base64Url === '' ? undefined : `url('${base64Url}')`,
      }}
    />,
  )
}
